package org.microframework.cloud.gateway.filter;

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * 安全头部过滤器
 * 为所有响应添加安全相关的HTTP头
 */
@Component
public class SecurityHeadersFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        return chain.filter(exchange).then(Mono.fromRunnable(() -> {
            ServerHttpResponse response = exchange.getResponse();
            HttpHeaders headers = response.getHeaders();
            
            // 添加安全相关的HTTP头
            
            // 防止浏览器MIME类型嗅探
            headers.add("X-Content-Type-Options", "nosniff");
            
            // 防止网页被嵌入到iframe中，避免点击劫持
            headers.add("X-Frame-Options", "DENY");
            
            // 启用XSS保护，并在检测到XSS攻击时阻止页面加载
            headers.add("X-XSS-Protection", "1; mode=block");
            
            // 强制使用HTTPS（仅当站点全站启用HTTPS时启用）
            headers.add("Strict-Transport-Security", "max-age=31536000; includeSubDomains");
            
            // 防止浏览器缓存敏感数据
            headers.add("Cache-Control", "no-store");
            headers.add("Pragma", "no-cache");
            
            // 内容安全策略，控制资源加载
            headers.add("Content-Security-Policy", "default-src 'self'");
            
            // 指示浏览器根据Content-Type解析响应而不是嗅探内容
            headers.add("X-Download-Options", "noopen");
            
            // 指示浏览器将发现的任何跨站脚本攻击报告给服务器
            headers.add("X-Permitted-Cross-Domain-Policies", "none");
            
            // 阻止浏览器发送Referer头到其他站点
            headers.add("Referrer-Policy", "no-referrer");
        }));
    }

    @Override
    public int getOrder() {
        // 设置为高优先级，但低于响应过滤器
        return Ordered.HIGHEST_PRECEDENCE + 20;
    }
} 